package it.uniroma2.art.coda.pearl.model;

import it.uniroma2.art.coda.interfaces.Converter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * A composition of converters.
 * 
 * @author <a href="fiorelli@info.uniroma2.it">Manuel Fiorelli</a>
 * 
 */
public class ConvertList implements Converter, Iterable<Converter> {

	/**
	 * A list of convertes in the order they will be executed.
	 */
	private List<Converter> converters;

	/**
	 * Default constructor. The resulting compound is equivalent to a
	 * copy-converter (which returns its input).
	 */
	public ConvertList() {
		converters = new ArrayList<Converter>();
	}

	/**
	 * Constructs a compound converter. The components will be executed
	 * according to the provided sequence.
	 * 
	 * @param converters
	 *            A sequence of converters
	 */
	public ConvertList(List<Converter> converters) {
		this.converters = converters;
	}

	/**
	 * Adds a converter to the compound.
	 * 
	 * @param converter
	 *            the converter to add
	 */
	public void add(Converter converter) {
		this.converters.add(converter);
	}

	/**
	 * Sets the i-th converter in the compound. Note that the index is
	 * zero-based.
	 * 
	 * @param index
	 *            the component index
	 * @param converter
	 *            the converter to use
	 */
	public void set(int index, Converter converter) {
		this.converters.set(index, converter);
	}

	/**
	 * Removes the i-th converter from the compound.
	 * 
	 * @param index
	 *            the component index
	 * @return the removed converter
	 */
	public Converter remove(int index) {
		return this.converters.remove(index);
	}

	/**
	 * Returns the constituent number.
	 * 
	 * @return the constituent number
	 */
	public int count() {
		return this.converters.size();
	}

	/*
	 * (non-Javadoc)
	 * @see it.uniroma2.art.coda.interfaces.Converter#apply(java.lang.String, java.lang.String)
	 */
	public String apply(String defaultNs, String value) {
		for (Converter conv : this.converters) {
			value = conv.apply(defaultNs, value);
		}

		return value;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Iterable#iterator()
	 */
	public Iterator<Converter> iterator() {
		return this.converters.iterator();
	}
}
